#include <unistd.h>
#include <errno.h>
#include <pthread.h>

#include "MobsBuf.h"

static const char *bufName = "/tmp/buf_2p2c.mobs";

void *mobs_producer(void*args)
{
    char user_name[32];
    snprintf(user_name,sizeof(user_name),"producer%02ld",(intptr_t)args);
    uintptr_t wuid = mobs_open(user_name,bufName,
	    MOBS_FLAG_CREATE|MOBS_FLAG_WRONLY|MOBS_FLAG_PRIVATE,1024*1024,1024,4096);
    printf("[%s] uid = 0x%08lx\n",user_name,wuid);

    int ret = 0,woid;
    char data[1024];
    size_t cnt = 0;
    while(1)
    {//test write
	ret = mobs_start(wuid,0);
	//printf("[%s]write start ret = %d\n",user_name,ret);
	if(ret < 0) 
	{
	    break;
	    //exit(EXIT_FAILURE);
	}

	snprintf(data,sizeof(data),"hello mobs - msg %02zu!",cnt++);

	woid = ret;
	ret = mobs_write(wuid,woid,data,strlen(data));
	printf("[%s]write data:%s ret = %d\n",user_name,data,ret);
	if(ret < 0)
	{
	    break;
	    //exit(EXIT_FAILURE);
	}
	mobs_finish(wuid,woid);

	sleep(1);
    }
    mobs_close(wuid);
    printf("[%s]close mobs wuid = 0x%08lx\n",user_name,wuid);
    return NULL;
}
void *mobs_consumer(void*args)
{
    char user_name[32];
    snprintf(user_name,sizeof(user_name),"consumer%02ld",(intptr_t)args);
    uintptr_t ruid = mobs_open(user_name,bufName,
	    MOBS_FLAG_CREATE|MOBS_FLAG_RDONLY|MOBS_FLAG_PRIVATE,
	    1024*1024,1024,4096);
    printf("[%s]uid = 0x%08lx\n",user_name,ruid);

    char data[1024];
    int ret = 0,roid;
    while(1)
    { //test read
	ret = mobs_start(ruid,0);
	//printf("[%s]read start ret = %d\n",user_name,ret);
	if(ret == MOBS_ERR_EMPTY)
	{
	    sleep(1);
	    continue;
	}
	else if(ret < 0) exit(EXIT_FAILURE);

	roid = ret;
	memset(data,0,sizeof(data));
	ret = mobs_read(ruid,roid,data,sizeof(data));
	printf("[%s]data:%s ret = %d\n",user_name,data,ret);
	if(ret == MOBS_ERR_INTERRUPTED)
	{// next
	}
	else if(ret < 0)
	{
	    break;
	    //exit(EXIT_FAILURE);
	}
	mobs_finish(ruid,roid);
    }
    mobs_close(ruid);
    printf("[%s]close mobs ruid = 0x%08lx\n",user_name,ruid);

    return NULL;
}

int main(int argc,char *argv[])
{
    int ret = 0;
    
    mobs_unlink(bufName);

    intptr_t i;
    int num = 2;
    if(argc >= 2)
    {
	num = atoi(argv[1]);
	if(num <= 0) num = 2;
    }

    pthread_t wtid[16],rtid[16];
    for(i=0;i<num;i++)
    {
	ret = pthread_create(&wtid[i],NULL,mobs_producer,(void*)i);
	ret = pthread_create(&rtid[i],NULL,mobs_consumer,(void*)i);
    }

    for(i=0;i<num;i++)
    {
	pthread_join(wtid[i],NULL);
	pthread_join(rtid[i],NULL);
    }

    return ret;
}

